package com.globallogic.javatrainings.sergiiivanov.model;

import java.io.Serializable;

import com.globallogic.javatrainings.sergiiivanov.resources.ErrorCodes;

/**
 * Connects personnel to university
 * 
 * @author Sergey
 * 
 */
public class PersonnelManager implements Serializable, NameUniqueObserver {
    private static final long serialVersionUID = 1L;
    private MyArray<Personnel> personnel;

    /**
     * Creates new instance
     */
    public PersonnelManager() {
        personnel = new MyArray<Personnel>(new Personnel[0]);
    }

    /**
     * Adds new personnel into collection if name is valid
     * 
     * @param name
     *            - valid name (not null, not empty, unique in collection)
     * @param mobile
     *            - set as is
     * @param email
     *            - set as is
     * @throws UniversityWarning
     *             name is not valid
     */
    public void addPersonnel(String name, String mobile, String email) throws UniversityWarning {
        if (name == Const.STRING_EMPTY || name == null) {
            throw new UniversityWarning(ErrorCodes.PERSON_NAME_NULL);
        }
        Personnel person = new Personnel();
        person.addObserver(this);
        person.setName(name);
        person.setMobile(mobile);
        person.setEmail(email);
        personnel.add(person);
    }

    /**
     * Returns {@link Personnel} stored in collection under index
     * 
     * @param index
     *            - valid index (0<=index<{@link #countPeople()})
     * @return {@link Personnel}
     * @throws UniversityWarning
     *             index is not valid
     * @throws UniversityFailure
     *             code crashes
     */
    public Personnel getPersonnelByIndex(int index) throws UniversityFailure, UniversityWarning {
        checkPersonnelIndex(index);
        return personnel.get(index);
    }

    private void checkPersonnelIndex(int index) throws UniversityWarning {
        if (index < 0 || countPeople() <= index) {
            throw new UniversityWarning(
                    ErrorCodes.PERSONNEL_NOT_FOUND_BY_INDEX + Integer.toString(index));
        }
    }

    /**
     * Calculates number of records added by
     * {@link #addPersonnel(String, String, String)}
     * 
     * @return number of personnel
     */
    public int countPeople() {
        return personnel.size();
    }

    /**
     * Returns copy of personnel added by
     * {@link #addPersonnel(String, String, String)}
     * 
     * @return {@link MyArray#copy()} of {@link Personnel}
     * @throws UniversityFailure
     *             code crashes
     */
    public String[] getPersonnelList() throws UniversityFailure {
        return personnel.toNamesList();
    }

    /**
     * Removes personnel from the collection. If there is no such personnel -
     * nothing happens.
     * 
     * @param p
     *            - personnel from the collection
     * @throws UniversityFailure
     *             code crashes
     */
    public void removePerson(Personnel p) throws UniversityWarning {
        if( p== null || personnel.indexOf(p)<0 ){
            throw new UniversityWarning(ErrorCodes.PERSONNEL_NOT_FOUND);
        }
        p.removeLinks();
        personnel.remove(p);
    }

    /**
     * @throws UniversityWarning
     *             if name is found in collection
     */
    @Override
    public void hasDuplicates(String name) throws UniversityWarning {
        if (name != null) {
            for (MyArrayToNamesCovertable existingOne : personnel) {
                if (name.equals(existingOne.getName()))
                    throw new UniversityWarning(ErrorCodes.PERSON_NAME_NOT_UNIQUE + name);
            }
        }
    }

    /**
     * Returns copy of personnel collection
     * 
     * @return {@link MyArray} of {@link Personnel}
     */
    public MyArray<Personnel> getPersonnel() {
        return personnel.copy();
    }

}
